<template>
  <div class="mi-chat-section">
    <!--左边房间信息-->
    <!--    <div class="mi-room-info"></div>-->
    <!--中间聊天信息-->
    <div class="mi-room-msg">
      <div class="room-head">
        <div class="chat-user-setting"><i title="用户设置" class="fa fa-cog pointer ld ld-spin ld-by-hover"
                                          aria-hidden="true"
                                          @click="openDialog('userDialog')"></i></div>
        <span style="flex: 1;text-align: center">祖安聊天室</span>
      </div>
      <div class="msg-box" ref="msgScroll">
        <!--        <vue-scroll ref="msg-scroll">-->
        <div style="position: relative;width: 100%;">
          <div class="pulldown-wrapper">

            <div class="pulldown-info" v-show="beforePullDown">
              <span style="display: inline-block;margin-top: 15px;margin-bottom: 10px;font-size: 12px;">松开加载更多</span>
              <img style="width: 40px;height: 40px;" src="/image/others/loading-rect.svg"/>
            </div>

            <div class="pulldown-info" v-show="!beforePullDown">
              <div v-show="isPullingDown">
                <img style="margin-top: 50px;width: 40px;height: 40px;" src="/image/others/loading-rect.svg"/>
              </div>
              <div v-show="!isPullingDown">
                <img style="margin-top: 50px;width: 40px;height: 40px;" src="/image/others/ok-1.1s-47px.svg"/>
              </div>
            </div>
          </div>
          <div class="msg-container" v-for="(msg,i) in msgs" :key="i">
            <div class="sender-image-box">
              <span class="sender-image">
              <img :src="msg.sender.head" alt="">
              </span>
            </div>

            <div class="msg-info">
              <div class="send-info">
                <span class="sender-name" :class="{'is-me':msg.sender.id===sender.id}">{{ msg.sender.name }}</span>
                <span class="send-time" v-if="msg.sendTime">{{ formatSendTime(msg.sendTime) }}</span>
              </div>
              <div class="send-status" v-if="msg.status!==undefined&&msg.status===SENDING"><i
                  class="ld ld-ring ld-cycle"></i><span class="ml-5">发送中...</span></div>

              <div class="msg-detail">
                <p v-for="(item,i) in msg.content" :key="i">
                  {{ item }}
                </p>
              </div>
            </div>

          </div>
        </div>
        <!--        </vue-scroll>-->
      </div>
      <div class="msg-in-area">
        <div class="msg-in-wrapper">
          <div class="msg-input-wrapper">
            <div class="msg-input"
                 id="chat-msg-input-box"
                 ref="msg"
                 contenteditable="true"
                 @keydown="handleMsgBoxKeydown"
                 @keyup="enterKey"
            ></div>
          </div>
          <div class="msg-btn">
            <i title="发送" class="pointer fa fa-paper-plane ld ld-tremble ld-by-hover" @click="sendMsg"
               aria-hidden="true"></i>
          </div>
        </div>

      </div>

    </div>
    <!--右侧在线信息-->
    <div class="mi-room-people"
         :class="{hide:hideOnlineList}">
      <div class="room-head"><span v-show="!hideOnlineList">在线小伙伴 {{ onlineUser.length }}</span>
        <i class="ml-auto far fa-arrow-alt-circle-left pointer mr-2"
           :class="{active:hideOnlineList}"
           @click="hideOnlineList=!hideOnlineList"
        ></i></div>
      <div class="online-user-item" v-for="user in onlineUser" :key="user[0]">
        <span class="sender-image">
            <img :src="user[1].head" alt="">
        </span>
        <span class="ml-5">{{ user[1].name }}</span>
      </div>
    </div>

    <milk-dialog v-if="userDialog" title="修改你的信息" @close="userDialog=false">
      <div>
        <milk-input v-model="userInfoTemp.name" :show-button="false" label="昵称"></milk-input>
      </div>
      <div class="mt-10">
        <milk-input v-model="userInfoTemp.head" :show-button="false" label="头像"
                    aria-placeholder="输入你的邮箱(gravatar)"></milk-input>
      </div>

      <div slot="foot" class="f-y-center pt-5">
        <button class="daisy-btn warn-btn ml-auto" @click="userDialog=false">取 消</button>
        <button class="daisy-btn primary-btn ml-5" @click="saveUserInfo">保 存</button>
      </div>
    </milk-dialog>
  </div>
</template>

<script>
import util from '../../libs/util'
import { GetChatMessage } from '@/api/blog-api'
import userMixin from '../mixins/userMixin'

const SENDING = 0
const SENT = 1
const SHOW_LOADING_TIME = 600
const SHOW_FINISH_LOADING_TIME = 700
const OLD_MESSAGE_SIZE = 25

export default {
  name: 'Chat',
  mixins: [userMixin],
  data () {
    return {
      // scroll S
      msgScroll: null,
      beforePullDown: true,
      isPullingDown: false,
      // scroll E
      SENDING,
      SENT,
      socket: null,
      msgs: [],
      onlineUser: [],
      md5: null,

      hideOnlineList: false,
    }
  },

  mounted () {
    this.initScroll()
    this.initSocket()
    this.getOldMessage()
  },

  beforeDestroy () {
    this.socket.disconnect()
  },

  methods: {
    // 打开对话框
    openDialog (dialog) {
      if (dialog === 'userDialog') {
        this.openUserInfoDialog()
      }
      this[dialog] = true
    },

    saveUserInfo () {
      this.updateUserInfo()
      this.socket.emit('userUpdateProfile', this.convertUserHead())
    },

    formatSendTime (time) {
      return util.time.formatSendTime(time)
    },

    // 初始化better-scrol
    initScroll () {
      this.msgScroll = BetterScroll.createBScroll(this.$refs.msgScroll, {
        // pullDownLoad: true,
        scrollbar: true,
        mouseWheel: {
          speed: 100,
          invert: false,
          easeTime: 300
        },
        pullDownRefresh: {
          threshold: 80,
          stop: 60
        }
      })
      this.msgScroll.on('pullingDown', this.pullingDownHandler)
      this.msgScroll.on('scroll', this.scrollHandler)
    },

    // 初始化socket.io
    initSocket () {
      // 连接socket
      // this.socket = io('http://daisy-api.icu', { path: '/room/1' })
      let pre = process.env.NODE_ENV === 'production' ? '/ws/' : '/'
      this.socket = io(process.env.VUE_APP_WS_BASE_URL, { path: pre + 'room/1' })

      this.socket.on('connect', () => {
        // 1.发送当前用户信息给服务端
        this.socket.emit('userConnect', this.convertUserHead())

        // 2.接收服务端返回的用户列表
        this.socket.on('onlineUser', (userlist) => {
          // console.log('onlineUser', userlist)
          this.onlineUser = Object.entries(userlist)
        })

        // 处理socket断开
        this.socket.on('disconnect', (err) => {
          console.log('disconnect', err)
        })

        // 处理socket接收到的消息
        this.handleReceiveMessage()
      })
    },

    pullingDownHandler () {
      console.log('pullingDownHandler')
      console.log('trigger pullDown')
      this.beforePullDown = false
      this.isPullingDown = true
      this.getOldMessage(this.msgs[0]._id)
    },

    scrollHandler (pos) {
      // console.log(pos.y)
    },

    // 获取之前的消息
    getOldMessage (_id = null) {
      if (this.beforePullDown === false) {
        // 显示 loading
        this.isPullingDown = true
      }
      GetChatMessage({ limit: OLD_MESSAGE_SIZE, _id }).then(res => {
        // 显示 loading success
        this.isPullingDown = false
        if (_id) {
          setTimeout(() => {
            this.msgScroll.finishPullDown()
          }, SHOW_LOADING_TIME)

          setTimeout(() => {
            if (res.data.length > 0) {
              this.msgs.unshift(...res.data)
            }
            this.$nextTick(() => {
              this.beforePullDown = true
              this.msgScroll.refresh()
            })
          }, SHOW_FINISH_LOADING_TIME)
        } else {

          if (res.data.length > 0) {
            this.msgs.unshift(...res.data)
            this.$nextTick(() => {
              this.msgScroll.refresh()
              this.$nextTick(() => {
                this.msgScroll.scrollTo(0, this.msgScroll.maxScrollY, 600)
              })
            })
          }

        }
      }).catch(err => {
        console.log(err)
      })
    },

    // 处理接受到的服务端消息
    handleReceiveMessage () {
      // 处理普通消息
      this.socket.on('serverMsg', (msg) => {
        // console.log('serverMsg', msg)
        if (msg.sender.id === this.sender.id) {
          let l = this.msgs.length
          while (l) {
            --l
            if (this.msgs[l].clientId === msg.clientId) {
              this.msgs[l].sendTime = msg.sendTime
              this.msgs[l].status = SENT
              l = 0
            }
          }
          // console.log(this.msgs)
        } else {
          this.showMsg(msg)
        }
      })

      // 处理系统消息
      // 1.用户上线
      this.socket.on('oneUserIn', (msg) => {
        this.onlineUser.push(msg)
      })
      // 2.用户下线
      this.socket.on('oneUserOut', (msg) => {
        this.onlineUser.some((user, index) => {
          if (user[0] === msg.socketId) {
            this.onlineUser.splice(index, 1)
            return true
          }
        })
      })
      // 3.用户更新了详情
      this.socket.on('userUpdateProfile', (msg) => {
        // console.log('userUpdateProfile', msg)
        // console.log('userUpdateProfile', this.onlineUser)
        this.onlineUser.some((user, index) => {
          if (user[0] === msg[0]) {
            this.$set(this.onlineUser, index, msg)
            return true
          }
        })
      })
    },

    // 展示消息
    showMsg (msg) {
      this.msgs.push(msg)
      this.$nextTick(() => {
        this.msgScroll.refresh()
        this.$nextTick(() => {
          this.msgScroll.scrollTo(0, this.msgScroll.maxScrollY, 700)
        })
      })
    },

    // 发送消息
    sendMsg () {
      if (this.sender.head === '') {
        alert('请点击左上齿轮配置你的邮箱！')
        return
      }
      if (!this.validateMessage(this.$refs.msg.innerHTML)) {
        return
      }
      let pattern = /\n/g
      let msg = this.$refs.msg.innerHTML.split(pattern)
      // 获取gravatar

      let postMsg =
          {
            clientId: util.guid(),
            content: msg,
            sender: this.convertUserHead(),
            status: SENDING
          }
      this.socket && this.socket.emit('clientMsg', postMsg)
      this.showMsg(postMsg)
      this.$refs.msg.innerHTML = ''
    },

    validateMessage (msg) {
      let reg = /^\s*$/g
      if (reg.test(msg)) {
        alert('信息不能为空')
        this.$refs.msg.innerHTML = ''
        return false
      }
      return true
    },

    handleMsgBoxKeydown (event) {
      const code = event.keyCode
          ? event.keyCode
          : event.which
              ? event.which
              : event.charCode
      if (code == 13 && !event.shiftKey) {
        event.preventDefault()
        return false
      }
    },

    enterKey (event) {
      const code = event.keyCode
          ? event.keyCode
          : event.which
              ? event.which
              : event.charCode
      if (code == 13 && !event.shiftKey) {
        this.sendMsg()
      }
    }
  },
}
</script>

<style>
.mi-chat-section {
  display: flex;
  width: 100%;
  height: 100%;
  color: white;
}

.mi-room-info {
  position: relative;
  width: 230px;
  height: 100%;
  background-color: #2e333a;
}

/*******************************************聊天室中部 START*/

/*.msg-box::-webkit-scrollbar {display:none}*/
.chat-user-setting {
  font-size: 18px;
  color: #e5e5e5;
}

.mi-room-msg {
  display: flex;
  position: relative;
  flex-direction: column;
  height: 100%;
  flex-grow: 1;
  padding: 43px 0 10px;
  background-color: #383c44;
}

.msg-box {
  position: relative;
  width: 100%;
  flex-grow: 1;
  overflow: hidden;
}

.pulldown-wrapper {
  position: absolute;
  width: 100%;
  height: 1000px;
  padding: 20px;
  box-sizing: border-box;
  transform: translateY(-100%) translateZ(0);
  text-align: center;
  color: #313131;
  background-color: rgb(255, 255, 255);
}

.pulldown-info {
  display: flex;
  flex-direction: column;
  align-items: center;
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 100px;
}

.send-status {
  display: flex;
  align-items: center;
  margin: 4px;
  font-size: 16px;
}

.send-status > span {
  font-size: 12px;
}

.msg-detail p {
  overflow: hidden;
}

.msg-in-area {
  position: relative;
  width: 100%;
  padding: 0 20px;
}

.msg-in-wrapper {
  display: flex;
  border-radius: 8px;
  background-color: #8f8f8f54;
}

.msg-input-wrapper {
  flex: 1;
  border: 1px solid transparent;
  overflow-x: hidden;
}

.msg-input {
  outline: none;
  width: 100%;
  font-size: 14px;
  padding: 14px 10px;
  min-height: 46px;
  -webkit-user-modify: read-write-plaintext-only;
  -webkit-user-select: text;
  background-color: #00000020;
}

.msg-btn {
  text-align: right;
  flex: 0 0 80px;
  padding: 14px 10px 0;
  font-size: 18px;
  color: #e5e5e5;
}

/*******************************************聊天室中部 END*/

.room-head {
  display: flex;
  align-items: center;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 42px;
  line-height: 42px;
  color: #c3c3c3;
  padding: 0 12px;
  background-color: #303539;
  border-bottom: 1px solid #262729;
  overflow: hidden;
}

.room-head .fa-arrow-alt-circle-left {
  font-size: 30px;
  transition: .35s;
}

.room-head .fa-arrow-alt-circle-left.active {
  transform: rotate(180deg);
}

.mi-room-people {
  position: relative;
  width: 210px;
  height: 100%;
  padding-top: 43px;
  background-color: #30343a;
  transition: .35s ease-in-out;
}

.mi-room-people.hide {
  width: 60px;
}

.online-user-item {
  padding: 6px 10px;
  display: flex;
  align-items: center;
  justify-content: left;
}


@media (max-width: 768px) {
  .msg-in-area {
    padding: 0;
  }
}
</style>
